﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

using DotSpatial.Controls;
using DotSpatial.Symbology;


using DotSpatial.Topology;

using Point = System.Drawing.Point;
using SelectionMode = DotSpatial.Symbology.SelectionMode;


namespace HAGISV2
{
    public class HSelectMapFunction : HMapFunction
    {
        #region Private Variables

        private bool _isDragging;
        private Point _startPoint;
        private Coordinate _geoStartPoint;
        private Point _currentPoint;

        private readonly Pen _selectionPen;


        //加入一些特殊功能的支持，这里辅助用右键菜单

        private ContextMenu _context;

        public ContextMenu Context
        {
            get { return _context; }
            set { _context = value; }
        }



        #endregion

        #region Constructors

        /// <summary>
        /// Creates a new instance of SelectTool
        /// </summary>
        public HSelectMapFunction(IMap inMap)
            : base(inMap)
        {
            _selectionPen = new Pen(Color.Black) { DashStyle = DashStyle.Dash };
            YieldStyle = YieldStyles.LeftButton | YieldStyles.Keyboard;
        }

        #endregion

        /// <summary>
        ///
        /// </summary>
        /// <param name="e"></param>
        protected override void OnDraw(MapDrawArgs e)
        {

            if (this._standBy)
            {
                return;
                
            }



            if (_isDragging)
            {
                // don't draw anything unless we need to draw a select rectangle
                Rectangle r = Opp.RectangleFromPoints(_startPoint, _currentPoint);
                r.Width -= 1;
                r.Height -= 1;
                e.Graphics.DrawRectangle(Pens.White, r);
                e.Graphics.DrawRectangle(_selectionPen, r);
            }

            base.OnDraw(e);
           
        }

        /// <summary>
        /// Handles the MouseDown
        /// </summary>
        /// <param name="e"></param>
        protected override void OnMouseDown(GeoMouseArgs e)
        {

            if (this._standBy)
            {
                return;

            }

            

            if (e.Button == MouseButtons.Left)
            {
                _startPoint = e.Location;
                _geoStartPoint = e.GeographicLocation;
                _isDragging = true;
                Map.IsBusy = true;
            }


          
        }

        /// <summary>
        /// Handles pressing the delete key to remove features from the specified layer.
        /// </summary>
        /// <param name="e"></param>
        protected override void OnKeyDown(KeyEventArgs e)
        {

            if (this._standBy)
            {
                return;

            }

            base.OnKeyDown(e);

            if (e.KeyCode == Keys.Delete)
            {
                bool selectable = false;
                foreach (ILayer layer in Map.MapFrame.GetAllLayers())
                {
                    IFeatureLayer fl = layer as IFeatureLayer;
                    if (fl == null) continue;

                    if (fl.IsWithinLegendSelection())
                    {
                        selectable = true;
                        fl.RemoveSelectedFeatures();
                        break;
                    }
                }
                if (selectable == false)
                {
                    MessageBox.Show("没有可删除的图层！");
                }
            }
           
            if (Map != null) Map.MapFrame.Invalidate();
        }

        /// <summary>
        /// Handles MouseMove
        /// </summary>
        /// <param name="e"></param>
        protected override void OnMouseMove(GeoMouseArgs e)
        {
            if (this._standBy)
            {
                return;

            }

            base.OnMouseMove(e);

            int x = Math.Min(Math.Min(_startPoint.X, _currentPoint.X), e.X);
            int y = Math.Min(Math.Min(_startPoint.Y, _currentPoint.Y), e.Y);
            int mx = Math.Max(Math.Max(_startPoint.X, _currentPoint.X), e.X);
            int my = Math.Max(Math.Max(_startPoint.Y, _currentPoint.Y), e.Y);
            _currentPoint = e.Location;
            if (_isDragging)
            {
                Map.Invalidate(new Rectangle(x, y, mx - x, my - y));
            }
         
        }

        /// <summary>
        /// Handles the Mouse Up situation
        /// </summary>
        /// <param name="e"></param>
        protected override void OnMouseUp(GeoMouseArgs e)
        {

            if (this._standBy)
            {
                return;

            }

           


            if (Map == null) Map = e.Map;
            if (_isDragging == false) return;
            _currentPoint = e.Location;
            _isDragging = false;

            //Application.DoEvents();
            IEnvelope env = new Envelope(_geoStartPoint.X, e.GeographicLocation.X,
                _geoStartPoint.Y, e.GeographicLocation.Y);
            IEnvelope tolerant = env;

            if (_startPoint.X == e.X && _startPoint.Y == e.Y)
            {
                // click selection doesn't work quite right without some tiny tolerance.
                double tol = Map.MapFrame.ViewExtents.Width / 10000;
                env.ExpandBy(tol);
            }

            if (Math.Abs(_startPoint.X - e.X) < 8 && Math.Abs(_startPoint.Y - e.Y) < 8)
            {
                Coordinate c1 = e.Map.PixelToProj(new Point(e.X - 4, e.Y - 4));
                Coordinate c2 = e.Map.PixelToProj(new Point(e.X + 4, e.Y + 4));
                tolerant = new Envelope(c1, c2);
            }

            Map.MapFrame.SuspendEvents();
            HandleSelection(tolerant, env);
            Map.MapFrame.ResumeEvents();
            // Force an invalidate to clear the dotted lines, even if we haven't changed anything.
            e.Map.Invalidate();
            //e.Map.MapFrame.Initialize();
            
            base.OnMouseUp(e);
            Map.IsBusy = false;
        }

        private void HandleSelection(IEnvelope tolerant, IEnvelope strict)
        {
            Keys key = Control.ModifierKeys;
            if ((((key & Keys.Shift) == Keys.Shift) == false)
                && (((key & Keys.Control) == Keys.Control) == false))
            {
                // If they are not pressing shift, then first clear the selection before adding new members to it.
                IEnvelope region;
                



                //付，增加的代码

                this.InteractiveSystem.GisManager.LayerSystem.ClearSelection();


            }

            if ((key & Keys.Control) == Keys.Control)
            {
                IEnvelope region;
                //Map.InvertSelection(tolerant, strict, SelectionMode.Intersects, out region);
            }
            else
            {



                if (this.InteractiveSystem.CurrentLayer != null)
                {
                    VectorLayer layer = this.InteractiveSystem.CurrentLayer as VectorLayer;

                    if (layer != null)
                    {
                        layer.Select(tolerant, strict, SelectionMode.Intersects);


                    }

                }


            }
        }


    }
}
